#include "pch.h"
#include <algorithm>

struct Card
{
    int no = -1;
    Card() = default;
    Card(int no) : no(no)
    {
    }
};

struct CardInfo
{
    int value;
    enum Type
    {
        Unknown = 0,
        Single,
        Double,
        Three,
        ThreeOne,
        ThreeTwo,
        FourOneOne,
        Bomb,
        KingBomb,
        NotLegal
    } type;
};

const char *TypeChars[] =
    {
        "Unknown",
        "Single",
        "Double",
        "Three",
        "ThreeOne",
        "ThreeTwo",
        "FourOneOne",
        "Bomb",
        "KingBomb",
        "NotLegal"

};

struct CardSub
{
    std::vector<Card> m_Cards;
    std::vector<int> m_valueVec;
    std::map<int, unsigned int> m_valueCount;
    std::map<unsigned int, int> m_ValueCountReserved;
    
    CardInfo::Type type = CardInfo::Type::Unknown;

    CardSub() = default;
    CardSub(const std::vector<Card> &cards) : m_Cards(cards)
    {
        m_valueCount.clear();
        m_ValueCountReserved.clear();
        m_valueVec.clear();

        // Count the value
        for (const auto &card : m_Cards)
        {
            m_valueCount[card.no]++;
            m_valueVec.push_back(card.no);
        }

        for (const auto &vc : m_valueCount)
        {
            m_ValueCountReserved[vc.second] = m_ValueCountReserved[vc.first];
        };

        std::sort(this->m_valueVec.begin(), this->m_valueVec.end());

        this->type = Confirm();
    }
    void Log()
    {
        LOGI("type %s", TypeChars[(int)this->type]);
    }

    bool ShareSameNum()
    {
        return m_valueCount.size() == 1;
    };

    CardInfo::Type Confirm()
    {
        int len = m_Cards.size();
        int numValueCount = m_valueCount.size();
        bool isSameNum = this->ShareSameNum();

        auto it1 = m_ValueCountReserved.find(1);
        auto it2 = m_ValueCountReserved.find(2);
        auto it3 = m_ValueCountReserved.find(3);
        auto it4 = m_ValueCountReserved.find(4);

     

        if (it4 != m_ValueCountReserved.end() && this->m_Cards.size() == 6)
        {
            return CardInfo::Type::FourOneOne;
        }

        if (
            (m_Cards[0].no == 14 && m_Cards[1].no == 15) ||
            (m_Cards[0].no == 15 && m_Cards[1].no == 14))
        {
            return CardInfo::Type::KingBomb;
        }

        if (numValueCount == 1)
        {
            switch (len)
            {
            case 1:
                return CardInfo::Type::Single;
            case 2:
                return CardInfo::Type::Double;
            case 3:
                return CardInfo::Type::Three;
            case 4:
                return CardInfo::Type::Bomb;
            default:
            break;
            }
        }
        else if (numValueCount == 2)
        {
            switch (len)
            {
            case 4:
                // has a num count 3
                {
                    auto it3 = m_ValueCountReserved.find(3);
                    auto it1 = m_ValueCountReserved.find(1);

                    if (it3 != m_ValueCountReserved.end() && it1 != m_ValueCountReserved.end())
                    {
                        return CardInfo::Type::ThreeOne;
                    }
                    else
                    {
                        return CardInfo::Type::NotLegal;
                    }
                }


            case 5:
            {
                auto it3 = m_ValueCountReserved.find(3);
                auto it2 = m_ValueCountReserved.find(2);

                if (it3 != m_ValueCountReserved.end() && it2 != m_ValueCountReserved.end())
                {
                    return CardInfo::Type::ThreeTwo;
                }
                else
                {
                    return CardInfo::Type::NotLegal;
                }
            }
            default:
                break;
            }
        }
    
    }
};

#include <set>
#include <algorithm>

int main()
{
    CardSub c1({0});
    CardSub c2({0, 0});
    CardSub c3({0, 0, 0});
    CardSub c4({0, 0, 0, 0});
    CardSub c5({0, 0, 0, 1});
    CardSub c6({0, 0, 0, 1, 1});
    CardSub c7({0, 0, 0, 0, 1, 5});
    CardSub c8({14, 15});
    CardSub c9({0, 1, 2, 3, 4});

    c1.Log();
    c2.Log();
    c3.Log();
    c4.Log();
    c5.Log();
    c6.Log();
    c7.Log();
    c8.Log();

    // std::map<int, int> nos;

    // buyanjingde data



};